//
// Copyright © 2021 dev. All rights reserved.
// 

import RxSwift
import RxCocoa
import Cocoa

class WWDCTabViewController<Tab:RawRepresentable>: NSTabViewController where  Tab.RawValue == Int  {
    var activeTab: Tab {
        get {
            return Tab(rawValue: selectedTabViewItemIndex)!
        }
        set {
            selectedTabViewItemIndex = newValue.rawValue
        }
    }



    private var activeTabVar = BehaviorRelay<Tab>(value:Tab(rawValue:0)!)

    var rxActiveTab:Observable<Tab> {
        return activeTabVar.asObservable()
    }
    private(set) lazy var tabBar = WWDCTabViewControllerTabBar()

    override var selectedTabViewItemIndex: Int {
        didSet {
            guard selectedTabViewItemIndex != oldValue else { return  }

            guard selectedTabViewItemIndex >= 0 && selectedTabViewItemIndex < tabViewItems.count else { return  }
            tabViewItems.forEach { item in
                guard let identifier = item.viewController?.identifier else { return}
                guard let view = tabBar.items.first(where: { $0.controllerIdentifier == identifier.rawValue}) else { return}
                if indexForChild(with: identifier.rawValue) == selectedTabViewItemIndex {
                    view.state = .on
                }else {
                    view.state = .off
                }
            }
        }
    }
    init(windowController: WWDCWindowController ){
        super.init(nibName: nil, bundle: nil)
        windowController.titleBarViewController.tabBar = tabBar
        let superFrame = view.frame
        if let windowFrame = windowController.window?.frame {
            view.frame = NSRect(origin: superFrame.origin, size: windowFrame.size)
        }
        tabStyle = .unspecified
        identifier = NSUserInterfaceItemIdentifier(rawValue: "tabs")
    }

    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }

    override func addTabViewItem(_ tabViewItem: NSTabViewItem) {
        super.addTabViewItem(tabViewItem)
        let itemView =  TabItemView(frame: .zero)
        itemView.title = tabViewItem.label
        itemView.controllerIdentifier = (tabViewItem.viewController?.identifier).map { $0.rawValue } ?? ""
        itemView.image = NSImage(named: itemView.controllerIdentifier.lowercased())
        itemView.alternateImage = NSImage(named: itemView.controllerIdentifier.lowercased() + "-filled")
        itemView.sizeToFit()
        itemView.target = self
        itemView.action = #selector(changeTab)
        itemView.state = (tabViewItems.firstIndex(of: tabViewItem) == selectedTabViewItemIndex) ? .on : .off
        tabBar.addItem(itemView)
    }

var isTopConstraintAdded = false

    override func updateViewConstraints() {
        super.updateViewConstraints()
        if !isTopConstraintAdded, let window = view.window {
            isTopConstraintAdded = true
            NSLayoutConstraint(item: tabView, attribute: .top, relatedBy: .equal, toItem: window.contentLayoutGuide, attribute: .top, multiplier: 1, constant: 0).isActive = true
        }
    }

    override func transition(from fromViewController: NSViewController, to toViewController: NSViewController, options: NSViewController.TransitionOptions = [], completionHandler completion: (() -> Void)? = nil) {
        NSAnimationContext.runAnimationGroup { context in
            context.duration = 0
            self.transition(from: fromViewController, to: toViewController,options: options,completionHandler: completion)
        }
    }

@objc
    private   func changeTab(_ sender:TabItemView)  {
        guard let index = indexForChild(with: sender.controllerIdentifier) else { return  }
        selectedTabViewItemIndex = index
    }


    private var loadingView: ModalLoadingView?

    func showLoading()  {
        loadingView = ModalLoadingView.show(attachedTo: view)
    }
    func hideLoading()  {
        loadingView?.hide()
    }

   private lazy var backgroundView: NSVisualEffectView = {
        let v = NSVisualEffectView()
        v.material = .headerView
        v.state = .followsWindowActiveState
        v.appearance = NSAppearance(named: .darkAqua)
        v.blendingMode = .withinWindow
        v.translatesAutoresizingMaskIntoConstraints = false
        return v
    }()

    override func viewDidAppear() {
        super.viewDidAppear()
        installModernHeaderViewIfNeed()
    }
    func installModernHeaderViewIfNeed()  {
        guard
            #available(macOS 11.0, *)
        else {
            return
        }
        guard backgroundView.superview == nil else {
            return
        }
        view.addSubview(backgroundView)
        NSLayoutConstraint.activate([
                                        backgroundView.leadingAnchor.constraint(equalTo: view.leadingAnchor),
            backgroundView.trailingAnchor.constraint(equalTo: view.trailingAnchor),
            backgroundView.topAnchor.constraint(equalTo: view.topAnchor),
            backgroundView.bottomAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor)
        ])
    }


    private func indexForChild(with identifier:String) -> Int? {
        return tabViewItems.firstIndex{$0.viewController?.identifier?.rawValue == identifier}
    }



}
